fix: role-mention only matches bot's own roles (with guild_create cache)#246
fix: role-mention only matches bot's own roles (with guild_create cache)#246chengli wants to merge 1 commit intoopenabdev:mainfrom
Conversation
The existing role-mention check matched any role mentioned in the message, not just roles assigned to the receiving bot. In multi-bot guilds this caused cross-triggering: mentioning bot B's role would also wake up bot A. Replace string matching against msg.content with a set intersection against the bot's own cached role IDs. The cache is populated from guild_create events (not ready, which only has UnavailableGuild stubs for larger guilds) and stored in a RwLock<HashSet<u64>>. Early-exit when msg.mention_roles is empty to skip the cache read entirely. Closes openabdev#245
Review — PR #246Good fix for a real multi-bot guild problem. The approach is correct. ✅ What looks good
🔴 Must fix before merge1. Merge conflict with 2. CI not triggered 🟡 Non-blocking3. Role cache not updated after SummaryLogic is sound, minimal change, solves a real problem. Rebase onto |
chaodu-agent
left a comment
There was a problem hiding this comment.
🔴 STALE / OBSOLETE — Bug already fixed on main by removing role-mention detection entirely.
Baseline Check (Step 0)
| Field | Value |
|---|---|
| State | OPEN |
| Mergeable | CONFLICTING |
| Created | 2026-04-12 (19 days ago) |
| Changes | +41 / -4, 2 files |
| Labels | p2, closing-soon |
Main branch status: The current main branch is_mentioned logic is:
let is_mentioned = msg.mentions_user_id(bot_id)
|| msg.content.contains(&format!("<@{}>", bot_id));No role-mention detection at all. The cross-bot triggering bug was resolved by removing role-mention detection entirely.
Four-Question Framework
1. What problem does it solve?
In multi-bot guilds, the old is_mentioned logic checked msg.mention_roles with string matching — any role mention triggered ALL bots. PR fixes this by caching bot's own role IDs via guild_create events.
2. How does it solve it?
bot_role_ids: Arc<RwLock<HashSet<u64>>>on Handler- Populated via
guild_createevents (correct choice overready) - Set intersection against cached roles instead of string matching
- Early-exit when
msg.mention_rolesis empty
3. What was considered?
guild_create vs ready — well-reasoned. Flat HashSet vs per-guild HashMap — correctly notes Role IDs are globally unique.
4. Is it the best approach?
Technically sound for the problem it targets, but the problem no longer exists on main. Role-mention detection was removed entirely.
Traffic Light
🟢 INFO
- The
guild_createapproach is correct and well-documented Arc<RwLock<HashSet>>is the right concurrency pattern- Early-exit on empty
mention_rolesis a nice optimization - Excellent PR description
🔴 CRITICAL
- Bug already fixed on main — Role-mention detection was removed from
is_mentionedentirely. The cross-bot triggering issue no longer exists. - Handler struct completely refactored — Main's Handler now has
router,adapter,allow_bot_messages,trusted_bot_ids,participated_threads,multibot_threads,bot_turns,allow_dm. The PR targets the old struct. - Merge conflicts — Both files conflict with current main.
Recommendation: Close this PR. The bug is already fixed on main. If role-mention support is desired as a feature in the future, the guild_create caching approach from this PR is the right pattern and could be referenced.
Reviewed by 超渡法師 🔃 chaodu Backlog triage
|
Closing — the role-mention triggering bug was already resolved on main by removing role-mention detection from |
Summary
guild_createevents (notready) in aRwLock<HashSet>— zero per-message API callsmsg.mention_rolesis empty (skip cache read entirely)Closes #245
Details
Bug:
msg.mention_roles.iter().any(|r| msg.content.contains(...))triggers on any role mentioned in the message, not just the bot's own roles. In a guild with bots A (role X) and B (role Y), mentioning role Y incorrectly wakes up bot A.Fix: replace string matching with a set intersection against the bot's cached roles:
Technical notes:
Why
guild_createinstead ofready?ready.guildscontainsUnavailableGuildstubs. Guild member data may not be available yet, particularly for larger guilds, causing.member()lookups to 404.guild_createfires per guild afterreadywith complete data.Global
HashSetvs per-guildHashMap: We use a flatHashSet<u64>for the cache. Discord Role IDs are globally unique andmsg.mention_rolesonly contains roles valid for the current guild, so a flat cache is safe and keeps lookups simple.Known limitation: If a role is added to the bot while it is running, it won't be recognized until restart. A
guild_member_updatehandler could keep the cache hot if dynamic role assignment becomes a requested feature.Files changed
src/discord.rsbot_role_ids: Arc<RwLock<HashSet<u64>>>to Handler; replace string-match with cache lookup; addguild_createhandler to populate cachesrc/main.rsbot_role_idscacheTest plan
cargo checkpasses ✅ (verified locally)guild_create